package cn.c4ad.voa;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.TextView;

import java.io.File;
import java.util.ArrayList;

public class ListFragment extends Fragment {
	private ContentResolver mContentResolver;
	private ListView mListView;
	private TextView mHintView;
	private TextView mRightButton;
	private ArticalListAdapter mListAdapter;
	private LoadSpecialListTask mLoadSpecialListTask;
	private ContentObserver mContentObserver;
	private Loader<Cursor> mLoader;

	private Model.ArticalTypeParameter mParameter;

	protected int getArticalType() {
		return VoaContentProvider.TYPE_SPECIAL;
	}

	@Override
	public void onCreate(Bundle savedState) {
		super.onCreate(savedState);

		int type = getArticalType();
		mParameter = Model.getArticalTypeParameter(type);

		mListAdapter = new ArticalListAdapter(getActivity(), null);

		mLoader = getLoaderManager().initLoader(0, null,
				new LoaderCallbacks<Cursor>() {
					@Override
					public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
						return new CursorLoader(
								getActivity(),
								VoaContentProvider.ARTICAL_CONTENT_URI,
								null,
								VoaContentProvider.TYPE + "=?",
								new String[] { String.valueOf(mParameter.type) },
								VoaContentProvider.ID + " DESC LIMIT 50");
					}

					@Override
					public void onLoadFinished(Loader<Cursor> loader,
							Cursor cursor) {
						mListAdapter.swapCursor(cursor);
						refreshUi();
					}

					@Override
					public void onLoaderReset(Loader<Cursor> loader) {
					}
				});

		mContentObserver = new ContentObserver(new Handler()) {
			@Override
			public void onChange(boolean selfChange) {
				super.onChange(selfChange);
				mLoader.forceLoad();
			}
		};
		mContentResolver = getActivity().getContentResolver();
		mContentResolver.registerContentObserver(
				VoaContentProvider.ARTICAL_CONTENT_URI, true, mContentObserver);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		prepareActionBar();

		View rootView = inflater.inflate(R.layout.list_fragment, container,
				false);
		mListView = (ListView) rootView.findViewById(R.id.listView);
		mListView.setAdapter(mListAdapter);
		mListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				Cursor cursor = mListAdapter.getCursor();
				if (cursor != null && cursor.moveToPosition(position)) {
					long articalId = cursor.getLong(cursor
							.getColumnIndex(VoaContentProvider.ID));
					Intent intent = new Intent();
					intent.setClass(getActivity(), ArticalActivity.class);
					intent.putExtra(ArticalActivity.EXTRA_ID, articalId);
					getActivity().startActivity(intent);
				}
			}
		});

		mListView.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id) {
				Cursor cursor = mListAdapter.getCursor();
				if (cursor != null && cursor.moveToPosition(position)) {
					Activity activity = getActivity();
					final long articalId = cursor.getLong(cursor
							.getColumnIndex(VoaContentProvider.ID));
					PopupMenu popupMenu = new PopupMenu(activity, view
							.findViewById(R.id.title));
					Menu menu = popupMenu.getMenu();
					MenuInflater menuInflater = activity.getMenuInflater();
					menuInflater.inflate(R.menu.list_fragment_menu, menu);
					popupMenu
							.setOnMenuItemClickListener(new OnMenuItemClickListener() {
								@Override
								public boolean onMenuItemClick(MenuItem item) {
									switch (item.getItemId()) {
									case R.id.list_item_delete:
										deleteListItem(articalId);
										break;
									}
									return true;
								}
							});
					popupMenu.show();
				}
				return true;
			}
		});

		mHintView = (TextView) rootView.findViewById(R.id.hint);

		return rootView;
	}

	@Override
	public void onResume() {
		super.onResume();
		refreshUi();
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();

		mListView = null;
		mHintView = null;
		mRightButton = null;
	}

	@Override
	public void onDestroy() {
		mContentResolver.unregisterContentObserver(mContentObserver);
		super.onDestroy();
	}

	private void prepareActionBar() {
		View actionBarView = getActivity().getActionBar().getCustomView();
		TextView title = (TextView) actionBarView.findViewById(R.id.title);
		title.setText(mParameter.fragmentTitleResId);

		mRightButton = (TextView) actionBarView.findViewById(R.id.rightButton);
		mRightButton.setVisibility(View.VISIBLE);
		mRightButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				mLoadSpecialListTask = new LoadSpecialListTask();
				mLoadSpecialListTask.execute(0);
				refreshUi();
			}
		});
	}

	private void refreshUi() {
		if (mRightButton != null) {
			if (mLoadSpecialListTask == null) {
				mRightButton.setText(R.string.refresh);
				mRightButton.setClickable(true);
			} else {
				mRightButton.setText(R.string.downloading);
				mRightButton.setClickable(false);
			}
		}

		if (mListView != null && mHintView != null) {
			if (mLoadSpecialListTask == null) {
				mHintView.setText(R.string.list_fragment_hint);
			} else {
				mHintView.setText(R.string.downloading_net);
			}

			if (mListAdapter.getCount() > 0) {
				mListView.setVisibility(View.VISIBLE);
				mHintView.setVisibility(View.GONE);
			} else {
				mListView.setVisibility(View.GONE);
				mHintView.setVisibility(View.VISIBLE);
			}
		}
	}

	private class ArticalListAdapter extends CursorAdapter {

		public ArticalListAdapter(Context context, Cursor c) {
			super(context, c, 0);
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			int downloadState = cursor.getInt(cursor
					.getColumnIndex(VoaContentProvider.DOWNLOAD_STATE));
			String title = cursor.getString(cursor
					.getColumnIndex(VoaContentProvider.TITLE));

			int icon = 0;
			if (downloadState == VoaContentProvider.DOWNLOAD_STATE_LOADING_MP3) {
				icon = R.drawable.state_download;
			} else if (downloadState == VoaContentProvider.DOWNLOAD_STATE_NULL) {
				icon = R.drawable.state_new;
			}

			ImageView iconView = (ImageView) view.findViewById(R.id.state_icon);
			TextView titleView = (TextView) view.findViewById(R.id.title);

			iconView.setImageResource(icon);
			titleView.setText(title);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			return LayoutInflater.from(context).inflate(R.layout.list_item,
					parent, false);
		}
	}

	private class LoadSpecialListTask extends
			AsyncTask<Integer, Integer, Integer> {

		String listUrl;
		String titleRegex;
		int type;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();

			type = mParameter.type;
			listUrl = mParameter.listUrl;
			titleRegex = mParameter.titleRegex;
		}

		@Override
		protected Integer doInBackground(Integer... arg0) {
			ArrayList<String[]> specialList = Model.getArticalList(listUrl,
					titleRegex);
			for (int i = specialList.size() - 1; i >= 0; i--) {
				String[] item = specialList.get(i);
				if (isArticalInDatabase(item[0])) {
					specialList.remove(i);
				}
			}

			for (int i = specialList.size() - 1; i >= 0; i--) {
				String[] item = specialList.get(i);
				ContentValues values = new ContentValues();
				values.put(VoaContentProvider.TYPE, type);
				values.put(VoaContentProvider.URL, item[0]);
				values.put(VoaContentProvider.TITLE, item[1]);
				mContentResolver.insert(VoaContentProvider.ARTICAL_CONTENT_URI,
						values);
			}

			return 0;
		}

		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);

			mLoadSpecialListTask = null;
			refreshUi();
		}
	}

	private boolean isArticalInDatabase(String url) {
		boolean exist = false;
		Cursor cursor = mContentResolver.query(
				VoaContentProvider.ARTICAL_CONTENT_URI,
				new String[] { VoaContentProvider.URL }, VoaContentProvider.URL
						+ "=?", new String[] { url }, null, null);

		if (cursor != null) {
			if (cursor.moveToFirst()) {
				exist = true;
			}
			cursor.close();
		}
		return exist;
	}

	private void deleteListItem(long id) {
		Uri uri = ContentUris.withAppendedId(
				VoaContentProvider.ARTICAL_CONTENT_URI, id);
		Cursor cursor = mContentResolver.query(uri, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			int downloadState = cursor.getInt(cursor
					.getColumnIndex(VoaContentProvider.DOWNLOAD_STATE));
			if (downloadState == VoaContentProvider.DOWNLOAD_STATE_LOADING_MP3) {
				long downloadId = cursor.getLong(cursor
						.getColumnIndex(VoaContentProvider.DOWNLOAD_ID));
				if (downloadId > 0) {
					DownloadManager downloadManager = (DownloadManager) getActivity()
							.getSystemService(Activity.DOWNLOAD_SERVICE);
					downloadManager.remove(downloadId);
				}
			} else if (downloadState == VoaContentProvider.DOWNLOAD_STATE_COMPLETED_ALL) {
				String mp3url = cursor.getString(cursor
						.getColumnIndex(VoaContentProvider.MP3URL));
				String name = Model.generateFileNameByUrl(mp3url);
				if (!TextUtils.isEmpty(name)) {
					File file = new File(getActivity()
							.getExternalFilesDir(null), name + ".mp3");
					if (file.exists()) {
						file.delete();
					}
				}
			}
		}

		mContentResolver.delete(uri, null, null);
	}
}
